package com.example.a2032.Utils;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CallLog;
import android.provider.ContactsContract;
import android.provider.Telephony;
import android.telephony.SmsManager;
import android.text.TextUtils;
import android.util.Log;

import com.example.a2032.db.DataDbHelper;
import com.example.a2032.entity.Contact;
import com.example.a2032.entity.SmsInfo;
import com.example.a2032.net.jstylenet.BindContactData;
import com.example.a2032.net.jstylenet.ContactData;
import com.example.a2032.net.jstylenet.UploadCallLogs;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.functions.Consumer;

public class ContactUtils {
    private static final String TAG = "ContactUtils";

    public static void addContact(Context context, BindContactData bindContactData) {
        String phoneNumber = bindContactData.getPhone();
        String name = bindContactData.getName();
        Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
                addContact(context, phoneNumber, name);
                emitter.onComplete();
            }
        }).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {

            }
        });

    }

    public static void deleteContact(Context context, BindContactData bindContactData) {
        String phoneNumber = bindContactData.getPhone();
        String name = bindContactData.getName();
        Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
                deleteContact(context, phoneNumber);
            }
        }).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {

            }
        });

    }

    public static void addContact(Context context, String phoneNumber, String name) {
        Log.i(TAG, "addContact: " + phoneNumber);

        if (isContactExits(context, phoneNumber)) {
            updateContact(context, phoneNumber, name);
            return;
        }
        Log.i(TAG, "addContact: add");
        ContentResolver contentResolver = context.getContentResolver();
        ContentValues contentValues = new ContentValues();
        long contactId = ContentUris.parseId(contentResolver.insert(ContactsContract.RawContacts.CONTENT_URI, contentValues));
        Uri uriContacts = ContactsContract.Data.CONTENT_URI;
        contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, contactId);
        contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
        contentResolver.insert(uriContacts, contentValues);
        contentValues.clear();
        contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, contactId);
        contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
        contentValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phoneNumber);
        contentResolver.insert(uriContacts, contentValues);

    }

    public static void addContact(Context context, ContactData contactData) {

        String id = contactData.getId();
        String phoneNumber = contactData.getPhone();
        String name = contactData.getName();
        Log.i(TAG, "addContact: add");
        ContentResolver contentResolver = context.getContentResolver();
        ContentValues contentValues = new ContentValues();
        long contactId = ContentUris.parseId(contentResolver.insert(ContactsContract.RawContacts.CONTENT_URI, contentValues));
        Uri uriContacts = ContactsContract.Data.CONTENT_URI;
        contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, contactId);
        contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name);
        contentResolver.insert(uriContacts, contentValues);
        contentValues.clear();
        contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, contactId);
        contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
        contentValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phoneNumber);
        contentValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
        contentResolver.insert(uriContacts, contentValues);
        contactData.setContactId(contactId);
        DataDbHelper.getInstance(context).getContactDataDao().insert(contactData);
    }


    public static void deleteContact(Context context, String number) {

        //根据姓名求id
        Uri uriContent = ContactsContract.Data.CONTENT_URI;
        Uri uriRawContent = ContactsContract.RawContacts.CONTENT_URI;
        ContentResolver resolver = context.getContentResolver();
        String where = ContactsContract.CommonDataKinds.Phone.NUMBER;
        Cursor cursor = resolver.query(uriContent, new String[]{ContactsContract.Data.RAW_CONTACT_ID}, where + "=?", new String[]{number}, null);
        while (cursor.moveToNext()) {
            int id = cursor.getInt(0);
            //根据id删除data中的相应数据
            resolver.delete(uriContent, ContactsContract.Data.RAW_CONTACT_ID + "=?", new String[]{id + ""});
            resolver.delete(uriRawContent, ContactsContract.RawContacts.CONTACT_ID + "=?", new String[]{id + ""});
        }

    }

    /**
     * 根据id删除联系人
     *
     * @param context
     * @param id
     */
    public static void deleteContact(Context context, long id) {
        Uri uriContent = ContactsContract.Data.CONTENT_URI;
        Uri uriRawContent = ContactsContract.RawContacts.CONTENT_URI;
        ContentResolver resolver = context.getContentResolver();
        resolver.delete(uriContent, ContactsContract.Data.RAW_CONTACT_ID + "=?", new String[]{id + ""});
        resolver.delete(uriRawContent, ContactsContract.RawContacts.CONTACT_ID + "=?", new String[]{id + ""});
    }

    public static void deleteAllContact(Context context) {
        Uri uriContent = ContactsContract.Data.CONTENT_URI;
        Uri uriRawContent = ContactsContract.RawContacts.CONTENT_URI;
        ContentResolver resolver = context.getContentResolver();
        String where = ContactsContract.Data.MIMETYPE;
        Cursor cursor = resolver.query(uriContent, new String[]{ContactsContract.Data.RAW_CONTACT_ID}, null, null, null);
        while (cursor.moveToNext()) {
            int id = cursor.getInt(0);
            //根据id删除data中的相应数据
            resolver.delete(uriContent, ContactsContract.Data.RAW_CONTACT_ID + "=?", new String[]{id + ""});
            resolver.delete(uriRawContent, ContactsContract.RawContacts.CONTACT_ID + "=?", new String[]{id + ""});
        }


        Log.i(TAG, "deleteAllContact: ");

    }

    public static void updateContact(Context context, String phoneNumber, String name) {
        Log.i(TAG, "updateContact: " + phoneNumber);
        Uri uri = ContactsContract.Data.CONTENT_URI;
        ContentResolver resolver = context.getContentResolver();
        String where = ContactsContract.Data.MIMETYPE;
        Cursor cursor = resolver.query(uri, null, where + "=? and data1 =?", new String[]{ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE, phoneNumber}, null);
        while (cursor.moveToNext()) {
            String id = cursor.getString(cursor
                    .getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID));
            String phone = cursor.getString(cursor
                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            Log.i(TAG, "updateContact: " + phone + " " + id);
            ContentValues values = new ContentValues();
            values.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
            resolver.update(uri, values, ContactsContract.Data.RAW_CONTACT_ID + "=? and mimetype =?", new String[]{id + "", ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE});
        }
        cursor.close();

    }

    /**
     * 根据id更新名字跟电话号码
     * (频繁更新名字会发现系统拨号界面会有名字显示错误)
     *
     * @param context
     * @param id
     * @param phoneNumber
     * @param name
     */
    public static void updateContact(Context context, long id, String phoneNumber, String name) {
        Log.i(TAG, "updateContact: " + phoneNumber);
        Uri uri = ContactsContract.Data.CONTENT_URI;
        ContentResolver resolver = context.getContentResolver();
        ContentValues values = new ContentValues();
        values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name);
        resolver.update(uri, values, ContactsContract.Data.RAW_CONTACT_ID + "=?  and mimetype =?", new String[]{id + "", ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE});
        values.clear();
        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phoneNumber);
        resolver.update(uri, values, ContactsContract.Data.RAW_CONTACT_ID + "=? and mimetype =?", new String[]{id + "", ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE});


    }

    public static boolean isContactExits(Context context, String phoneNumber) {
        Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + phoneNumber);
        ContentResolver resolver = context.getContentResolver();
        Cursor cursor = resolver.query(uri, new String[]{ContactsContract.Data.DISPLAY_NAME}, null, null, null);
        boolean isExist = cursor.moveToFirst();
        Log.i(TAG, "isContactExits: " + phoneNumber + " " + isExist);
        cursor.close();
        return isExist;
    }


    /**
     * 获取所有联系人
     * 先获取id然后再根据id获取电话号码的时候发现，存电话号码的那个数据库里的id跟data数据库查出来的id并不匹配，原因未知
     * 现在直接在data数据库里查询，联系人信息全部在data数据库里，字段data1数据类型有名字跟电话号码的区分
     *
     * @param context
     * @return
     */
    public static List<Contact> getAllContact(Context context) {
        List<Contact> list = new ArrayList<>();
        Cursor cursor = context.getContentResolver().query(
                ContactsContract.Data.CONTENT_URI, null, null, null, null);
        HashMap<String, Contact> contactMap = new HashMap<>();
        while (cursor.moveToNext()) {
            String data = cursor.getString(cursor
                    .getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));

            String contactId = cursor.getString(cursor
                    .getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID));
            String type = cursor.getString(cursor
                    .getColumnIndex(ContactsContract.Data.MIMETYPE));
            Contact contact = contactMap.get(contactId);
            if (contact == null) {
                contact = new Contact();
                contactMap.put(contactId, contact);
            }
            if (type.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)) {
                contact.setName(data);
            } else if (type.equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
                contact.setPhoneNumber(data);
            }
            Log.i(TAG, "getAllContact: " + data + " " + contactId + " " + type);
//            Cursor phoneCursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
//                    null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null);
//            Cursor phoneCursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
//                    null, null, null, null);
//            String phone = "";
//            while (phoneCursor.moveToNext()) {
//                phone = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
//                String id = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
//                Log.i(TAG, "getAllContact: phone" + phone+" "+id);
//                phone = phone.replace("-", "");
//                phone = phone.replace(" ", "");
//            }
//            Contact contact = new Contact();
//            contact.setName(data);
//            contact.setPhoneNumber(phone);
//            list.add(contact);
            //  phoneCursor.close();
        }
        for (Map.Entry<String, Contact> map : contactMap.entrySet()) {
            list.add(map.getValue());
        }
        return list;
    }

    //通话记录的名字如果之前没保存号码会返回null，保存后这条通话记录返回的还是null;
    //在保存后再出现的新的通话记录这个号码才会有名字
    //修改名字之后旧的通话记录也是之前的名字
    //上传通话记录的时候用最新的名字还是直接用通话记录生成时候的名字？
    public static List<UploadCallLogs> getCallLogs(Context context, String time) {
        long queryTime = TextUtils.isEmpty(time) ? 0 : DateUtils.fullFormatDate2Mil(time);
        List<UploadCallLogs> callLogs = new ArrayList<>();
        Uri callLogUri = CallLog.Calls.CONTENT_URI;
        String[] columns = {CallLog.Calls.CACHED_NAME// 通话记录的联系人
                , CallLog.Calls.NUMBER// 通话记录的电话号码
                , CallLog.Calls.DATE// 通话记录的日期
                , CallLog.Calls.DURATION// 通话时长
                , CallLog.Calls.TYPE};// 通话类型}
        ContentResolver contentResolver = context.getContentResolver();
        String selection=CallLog.Calls.DATE+" >?";
        String[]selectionArgs=new String[]{queryTime+""};
        Cursor cursor = contentResolver.query(callLogUri, columns, selection, selectionArgs, CallLog.Calls.DEFAULT_SORT_ORDER);
        while (cursor.moveToNext()) {
            long dateLong = cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE)); //获取通话日期
          //  if (dateLong < queryTime) continue;
            String name = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));  //姓名
            String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));  //号码
            int duration = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.DURATION));//获取通话时长，值为多少秒
            int type = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE)); //获取通话类型：1.呼入2.呼出3.未接
            UploadCallLogs uploadCallLogs = new UploadCallLogs();
            uploadCallLogs.setDuration(duration);
            uploadCallLogs.setType(type);
            uploadCallLogs.setPhone(number);
            uploadCallLogs.setTime(DateUtils.getFullDefaultDate(new Date(dateLong)));
            callLogs.add(uploadCallLogs);
            //Log.i(TAG, "getCallLogs: "+name+" "+number+" "+DateUtils.getDefaultDate(new Date(dateLong))+" "+duration+" "+type);
        }
        cursor.close();
        return callLogs;
    }

    public static void deleteAllCallLogs(Context context) {
        Uri callLogUri = CallLog.Calls.CONTENT_URI;
        ContentResolver contentResolver = context.getContentResolver();
        contentResolver.delete(callLogUri, null, null);
    }

    /**
     * 查询所有短信（需要设备更新，之前版本设备没有存）
     * @param context
     * @param time 服务器上存储的最后一条短信的时间，精确到毫秒
     * @return
     */
    public static List<SmsInfo> getAllSmsInfo(Context context,String time) {
        long queryTime = TextUtils.isEmpty(time) ? 0 : DateUtils.fullFormatDate2Mil(time);
        List<SmsInfo>list=new ArrayList<>();
        ContentResolver contentResolver=context.getContentResolver();
        String[]projection=new String[]{Telephony.Sms._ID,Telephony.Sms.ADDRESS,Telephony.Sms.BODY,Telephony.Sms.DATE,Telephony.Sms.TYPE};
        String selection=Telephony.Sms.TYPE+"= ? and "+ Telephony.Sms.DATE+" >?";
        String[]selectionArgs=new String[]{Telephony.Sms.MESSAGE_TYPE_INBOX+"",queryTime+""};
        Cursor cursor=contentResolver.query(Telephony.Sms.Inbox.CONTENT_URI,projection,selection,selectionArgs,null);
        while (cursor.moveToNext()){
            String address=cursor.getString(cursor.getColumnIndex(Telephony.Sms.ADDRESS));
            long dateLong=cursor.getLong(cursor.getColumnIndex(Telephony.Sms.DATE));
            String info=cursor.getString(cursor.getColumnIndex(Telephony.Sms.BODY));
            SmsInfo smsInfo=new SmsInfo();
            smsInfo.setContent(info);
            smsInfo.setCreated(DateUtils.getFullDefaultDate(new Date(dateLong)));
            smsInfo.setSender(address);
            list.add(smsInfo);
        }
        return list;
    }
}
